use std::collections::HashMap;

use bytes::{BufMut, BytesMut};
use http_body_util::BodyExt;
use hyper::Request;
use hyper_util::rt::TokioIo;
use serde_json::Value;
use tokio::net::TcpStream;
use tracing::{debug, error};

use crate::{error::Error, ResultEx};

pub async fn send_post_request(url: &str, body: String) -> ResultEx<HashMap<String, Value>> {
	debug!("向{} 发送请求,\nbody:{}", url, &body);

	let url = match url.trim().parse::<hyper::Uri>() {
		Ok(url) => url,
		Err(_) => return Err(Error::UniversalError("无效的url数据")),
	};

	let Some(host) = url.host() else {
		return Err(Error::UniversalError("url没有host数据"));
	};
	let port = url.port_u16().unwrap_or(80);
	let addr = format!("{}:{}", host, port);
	let Ok(stream) = TcpStream::connect(addr).await else {
		return Err(Error::UniversalError("连接服务器失败"));
	};
	let io = TokioIo::new(stream);

	let Ok((mut sender, conn)) = hyper::client::conn::http1::handshake(io).await else {
		return Err(Error::UniversalError("连接服务器失败..没有conn"));
	};
	tokio::task::spawn(async move {
		if let Err(err) = conn.await {
			error!("连接失败:{}", err);
		}
	});

	let path = url.path();
	let req = Request::builder()
		.uri(path)
		.method("POST")
		.header("Content-Type", "application/json")
		.header("User-Agent", "Apache-HttpClient")
		.header("Host", "www.400pt.net")
		.body(body)
		.unwrap();
	let Ok(mut res) = sender.send_request(req).await else {
		return Err(Error::UniversalError("发送请求异常"));
	};

	debug!("Response: {}", res.status());
	// debug!("Headers: {:#?}\n", res.headers());

	let mut res_body = BytesMut::with_capacity(200);
	while let Some(Ok(next)) = res.frame().await {
		let frame = next;
		if let Some(chunk) = frame.data_ref() {
			res_body.put_slice(chunk)
		}
	}
	let Ok(res_body_str) = std::str::from_utf8(&res_body) else {
		return Err(Error::UniversalError("解析body异常"));
	};

	debug!("得到的resbody:{}", res_body_str);
	let Ok(vv) = serde_json::from_str::<HashMap<String, Value>>(res_body_str) else {
		return Err(Error::UniversalError("解析body异常"));
	};

	Ok(vv)
}
